home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / msn / P2P / DCSocket.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  416 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from util import callsback, get, PriorityProducer, RoundRobinProducer, try_this
  5. from util.Events import EventMixin, event
  6. import struct
  7. import common
  8. import msn
  9. from msn.P2P.P2PData import P2PTransport, randid, Header, Flags
  10. import logging
  11. log = logging.getLogger('msn.dc')
  12. sock_in = logging.getLogger('msn.dc.sock.in')
  13. sock_out = logging.getLogger('msn.dc.sock.out')
  14.  
  15. class MSNDCProtocol(P2PTransport):
  16.     events = P2PTransport.events | set(('on_close', 'on_error', 'on_ready', 'on_connect', 'recv_data'))
  17.     
  18.     def __init__(self, client, peer, serving, mynonces, theirnonces):
  19.         EventMixin.__init__(self)
  20.         log.info('MSNDCProtocol created')
  21.         self.client = client
  22.         self.peer = peer
  23.         self.socket = None
  24.         self._MSNDCProtocol__connecter_class = None if serving else MSNDC_Client
  25.         (self.out_key, self.out_hkey) = mynonces
  26.         (self.in_key, self.in_hkey) = theirnonces
  27.         self.hashed = False
  28.         self.mine = True
  29.         self._MSNDCProtocol__sentnonce = False
  30.         self.rrobin = None
  31.         log.critical('MSNDC created: %r', self)
  32.  
  33.     
  34.     def purge_messages(self):
  35.         if get(self, 'socket', None) is not None:
  36.             log.info('Purging P2P messages back to P2P manager. Data in out buffer? %r', self.socket.ac_out_buffer)
  37.             while self.socket.producer_fifo:
  38.                 (__, prod) = self.socket.producer_fifo.pop()
  39.                 if hasattr(prod, 'msg'):
  40.                     prod.msg.reset()
  41.                     self.client._p2p_manager.send_message(prod.msg)
  42.                     continue
  43.                 if prod is not None:
  44.                     log.error('Not re-sending the following producer: %r', prod)
  45.                     continue
  46.         
  47.  
  48.     
  49.     def Connect(self, ips = None):
  50.         args = None if ips is None else (ips,)
  51.         self._connecter = self._MSNDCProtocol__connecter_class(*args)
  52.         self._connecter.connect(success = self._connected, error = self._timeout)
  53.         del self._MSNDCProtocol__connecter_class
  54.  
  55.     
  56.     def _connected(self, sock):
  57.         self._connecter.cleanup()
  58.         old_data = get(sock, 'data', '')
  59.         del self._connecter
  60.         self.socket = MSNDCSocket(sock, old_data)
  61.         
  62.         bind = lambda n, f: EventMixin.bind(self.socket, n, f)
  63.         bind('on_message', self.incoming)
  64.         bind('on_error', self._sck_closed)
  65.         bind('on_close', self._sck_closed)
  66.         bind('on_send', self.send_data)
  67.         self.rrobin = RoundRobinProducer(self.socket)
  68.         P2PTransport.__init__(self, self.client)
  69.         self.event('on_connect')
  70.         self.rrobin.unqueue()
  71.         self.rrobin.queue()
  72.  
  73.     
  74.     def incoming(self, data):
  75.         if not data:
  76.             return None
  77.         
  78.         if data.startswith('foo'):
  79.             log.warning('Got "foo"')
  80.             return None
  81.         
  82.         self.event('recv_data', self, self.peer, data, False)
  83.  
  84.     
  85.     def _send_nonce(self, msgid, msgidack):
  86.         self._super_secret_msgid = msgidack
  87.         if self._MSNDCProtocol__sentnonce:
  88.             log.warning('not sending nonce')
  89.             return None
  90.             sessid = self.sessid
  91.             log.warning('Sending nonce again, this time with session id')
  92.         else:
  93.             sessid = 0
  94.         msgid += self._MSNDCProtocol__sentnonce
  95.         owner = None if self.mine else 'their'
  96.         if self.hashed:
  97.             log.warning('Sending %s hashed-nonce', owner)
  98.             if self.mine:
  99.                 nonce = self.out_hkey
  100.             else:
  101.                 nonce = self.in_hkey
  102.         else:
  103.             log.warning('Sending %s unhashed-nonce', owner)
  104.             if self.mine:
  105.                 nonce = self.out_key
  106.             else:
  107.                 nonce = self.in_key
  108.         if nonce is None:
  109.             return None
  110.         
  111.         self._MSNDCProtocol__sentnonce = True
  112.         data = Header(session = sessid, msgid = msgid, flags = Flags.DCHS).pack()[:-16] + nonce.bytes_le
  113.         log.warning('Their nonces: unhashed=%r, hashed=%r', self.in_key, self.in_hkey)
  114.         log.warning('my nonces   : unhashed=%r, hashed=%r', self.out_key, self.out_hkey)
  115.         
  116.         try:
  117.             self.rrobin.unqueue()
  118.         except AttributeError:
  119.             pass
  120.  
  121.         self.socket._send(data)
  122.         self.event('on_ready')
  123.         self.rrobin.queue()
  124.  
  125.     
  126.     def send_data(self):
  127.         pass
  128.  
  129.     send_data = event(send_data)
  130.     
  131.     def _sck_closed(self):
  132.         if not hasattr(self, 'socket'):
  133.             return None
  134.         
  135.         log.critical('MSNDC socket has been closed.')
  136.         self.client._p2p_manager._unregister_transport(self)
  137.         if self.socket is not None:
  138.             
  139.             unbind = lambda n, f: EventMixin.unbind(self.socket, n, f)
  140.             unbind('on_message', self.incoming)
  141.             unbind('on_error', self._sck_closed)
  142.             unbind('on_close', self._sck_closed)
  143.             unbind('on_send', self.send_data)
  144.             self.socket.close_when_done()
  145.         
  146.         self.purge_messages()
  147.         self.event('on_error')
  148.         self.socket = None
  149.  
  150.     
  151.     def _timeout(self):
  152.         if hasattr(self, 'socket'):
  153.             self._sck_closed()
  154.         
  155.         self.event('on_error')
  156.  
  157.     
  158.     def Disconnect(self):
  159.         if hasattr(self, 'socket'):
  160.             log.critical('MSNDC closing socket now.')
  161.             self.socket.close_when_done()
  162.             self._sck_closed()
  163.         
  164.  
  165.     
  166.     def localport(self):
  167.         
  168.         try:
  169.             return self._connecter.localport
  170.         except:
  171.             
  172.             try:
  173.                 return self.socket.localport
  174.             return 0
  175.  
  176.  
  177.  
  178.     localport = property(localport)
  179.     
  180.     def p2p_peers(self):
  181.         return [
  182.             self.peer]
  183.  
  184.     p2p_peers = property(p2p_peers)
  185.     
  186.     def p2p_rating(self):
  187.         return 100
  188.  
  189.     p2p_rating = property(p2p_rating)
  190.     
  191.     def p2p_max_msg_size(self):
  192.         return 1400
  193.  
  194.     p2p_max_msg_size = property(p2p_max_msg_size)
  195.     
  196.     def p2p_overhead(self):
  197.         return 52
  198.  
  199.     p2p_overhead = property(p2p_overhead)
  200.     
  201.     def p2p_send(self, recvr, data, callback = None):
  202.         
  203.         try:
  204.             self.socket._send(data)
  205.         except:
  206.             callback.error()
  207.  
  208.  
  209.     p2p_send = callsback(p2p_send)
  210.     
  211.     def push_with_producer(self, prod, callback = None):
  212.         self.rrobin.add(prod)
  213.         log.info('Push with producer: %r, %r', self, prod)
  214.         self.rrobin.unqueue()
  215.         self.rrobin.queue()
  216.  
  217.     push_with_producer = callsback(push_with_producer)
  218.     
  219.     def build_data(self, header, body, footer):
  220.         data = header + body
  221.         return struct.pack('<I', len(data)) + data
  222.  
  223.  
  224.  
  225. class MSNDCSocket(common.socket, EventMixin):
  226.     hdr_size = 4
  227.     events = EventMixin.events | set(('on_message', 'on_close', 'on_error', 'on_send'))
  228.     
  229.     def __init__(self, conn, prev_data = ''):
  230.         common.socket.__init__(self, conn)
  231.         self.set_terminator(self.hdr_size)
  232.         self.ac_in_buffer = prev_data
  233.         EventMixin.__init__(self)
  234.         self.data = ''
  235.         self.getting_hdr = True
  236.  
  237.     
  238.     def collect_incoming_data(self, data):
  239.         self.data += data
  240.  
  241.     
  242.     def found_terminator(self):
  243.         data = self.data
  244.         self.data = ''
  245.         self.getting_hdr = not (self.getting_hdr)
  246.         if not self.getting_hdr:
  247.             (next_term,) = struct.unpack('<I', data)
  248.             if next_term:
  249.                 self.set_terminator(next_term)
  250.             else:
  251.                 self.found_terminator()
  252.         else:
  253.             self.set_terminator(self.hdr_size)
  254.             self.event('on_message', data)
  255.  
  256.     
  257.     def handle_close(self):
  258.         self.event('on_close')
  259.         common.socket.handle_close(self)
  260.         self.close()
  261.  
  262.     
  263.     def handle_expt(self):
  264.         self.event('on_error')
  265.         common.socket.handle_expt(self)
  266.  
  267.     
  268.     def handle_error(self, e = None):
  269.         import traceback as traceback
  270.         traceback.print_exc()
  271.         self.event('on_error')
  272.         self.close()
  273.         common.socket.handle_error(self, e)
  274.  
  275.     
  276.     def _send(self, data):
  277.         sock_out.log(5, '    MSNDCSocket Data out: %r', data[:100])
  278.         real_data = struct.pack('<I', len(data)) + data
  279.         return common.socket.push(self, real_data)
  280.  
  281.     
  282.     def __repr__(self):
  283.         pn = None
  284.         
  285.         try:
  286.             pn = self.socket.getpeername()
  287.         finally:
  288.             return '<%s connected to %r>' % (self.__class__.__name__, pn)
  289.  
  290.  
  291.     
  292.     def localport(self):
  293.         
  294.         try:
  295.             return self.socket.getsockname()[1]
  296.         except:
  297.             return 0
  298.  
  299.  
  300.     localport = property(localport)
  301.  
  302.  
  303. class MSNDCConnecter(EventMixin):
  304.     events = EventMixin.events | set(('timeout', 'connected'))
  305.     
  306.     def __init__(self, ips):
  307.         EventMixin.__init__(self)
  308.         self._ips = ips
  309.         self.data = ''
  310.  
  311.     
  312.     def connect(self):
  313.         raise NotImplementedError
  314.  
  315.     
  316.     def collect_incoming_data(self, data):
  317.         self.data += data
  318.  
  319.     
  320.     def bind(self, *a, **k):
  321.         return EventMixin.bind(self, *a, **k)
  322.  
  323.     
  324.     def _timeout(self):
  325.         pref = pref
  326.         import common
  327.         return pref('msn.direct.timeout', type = int, default = 5)
  328.  
  329.     _timeout = property(_timeout)
  330.  
  331.  
  332. class MSNDC_Server(common.TimeoutSocket, MSNDCConnecter):
  333.     
  334.     def __init__(self):
  335.         common.TimeoutSocket.__init__(self, False)
  336.         MSNDCConnecter.__init__(self, ())
  337.         self.set_terminator(0)
  338.  
  339.     
  340.     def connect(self, callback = None):
  341.         self.tryaccept(('', 0), callback.success, callback.error, self._timeout)
  342.  
  343.     connect = callsback(connect)
  344.     
  345.     def localport(self):
  346.         
  347.         try:
  348.             return self.socket.getsockname()[1]
  349.         except:
  350.             return 0
  351.  
  352.  
  353.     localport = property(localport)
  354.     
  355.     def cleanup(self):
  356.         self.del_channel()
  357.         self.close()
  358.  
  359.  
  360.  
  361. class MSNDC_Client(common.HydraSocket, MSNDCConnecter):
  362.     
  363.     def __init__(self, ips):
  364.         common.HydraSocket.__init__(self)
  365.         MSNDCConnecter.__init__(self, ips)
  366.  
  367.     
  368.     def connect(self, callback = None):
  369.         self._MSNDC_Client__callback = callback
  370.         self.tryconnect(self._ips, self.connected, callback.error, self._timeout, cls = BufferedTimeoutSocket)
  371.  
  372.     connect = callsback(connect)
  373.     
  374.     def connected(self, sck):
  375.         data = 'foo\x00'
  376.         if sck.send(struct.pack('<I', len(data)) + data) != 4 + len(data):
  377.             sck.close()
  378.             self.on_fail()
  379.             log.warning('Send of "foo" failed')
  380.             return None
  381.         else:
  382.             log.warning('Sent "foo"')
  383.             self._MSNDC_Client__callback(sck)
  384.  
  385.     
  386.     def cleanup(self):
  387.         pass
  388.  
  389.  
  390.  
  391. class BufferedTimeoutSocket(common.TimeoutSocket):
  392.     
  393.     def __init__(self, *a, **k):
  394.         common.TimeoutSocket.__init__(self, *a, **k)
  395.         self.set_terminator(0)
  396.         self._BufferedTimeoutSocket__data = ''
  397.  
  398.     
  399.     def collect_incoming_data(self, data):
  400.         self._BufferedTimeoutSocket__data += data
  401.  
  402.     
  403.     def recv(self, bytes):
  404.         if self._BufferedTimeoutSocket__data:
  405.             data = self._BufferedTimeoutSocket__data[:bytes]
  406.             self._BufferedTimeoutSocket__data = self._BufferedTimeoutSocket__data[bytes:]
  407.         else:
  408.             data = self.socket.recv(bytes)
  409.         return data
  410.  
  411.     
  412.     def handle_close(self):
  413.         self.socket.close()
  414.  
  415.  
  416.